from django.shortcuts import render

# Create your views here.
from rest_framework.viewsets import ViewSet
from django.conf import settings
from rest_framework.response import Response
from .utils import OAuthQQ,QQNetworkError
from .models import OauthUser
from users.serializers import UserModelSerializer
from rest_framework import status
from users.utils import CustomAuthUserModelBackend

class QQUserLoginViewSet(ViewSet):
    def url(self,request):
        """获取QQ登录地址"""
        qq = OAuthQQ(**settings.QQ_CONNECT)
        url = qq.url()
        return Response(url)

    def get_qq_user(self,request):
        """获取登录用户信息"""
        # 1. 获取客户端提交过来的code授权码
        code = request.query_params.get("code")
        state = request.query_params.get("state")
        if code is None:
            return Response({"detail":"对不起,QQ登录授权码丢失,请重新使用QQ登录!"})

        qq = OAuthQQ(**settings.QQ_CONNECT)
        try:
            # 2. 根据授权码获取access_token临时访问票据
            access_token,refresh_token = qq.get_access_token(code)
            # 3. 根据临时访问票据获取QQ用户的openID
            openid = qq.get_open_id(access_token)
            # print(openid)  # 4F65D2442D41B0D1639FD7FC14123B11
        except QQNetworkError:
            return Response({"detail":"网络发生异常,QQ登录失败!"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 4. 根据openid到数据库是否有QQ用户信息绑定记录
        try:
            qq_user = OauthUser.objects.get(name=1, openid=openid)
            """表示当前用户已经和QQ进行登录绑定,生成jwt状态即可"""
            # 返回jwt登录状态
            from rest_framework_jwt.settings import api_settings

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(qq_user.user)
            qq_user.user.token = jwt_encode_handler(payload)
            serializer = UserModelSerializer(instance=qq_user.user)
            return Response(serializer.data)

        except OauthUser.DoesNotExist:
            """表示当前用户没有进行QQ登录绑定,则让客户端显示绑定QQ和用户信息的表单页面"""
            # 5. 根据数据库查询结果返回登录状态或者进行QQ与用户信息绑定流程
            return Response({
                "access_token":access_token,
                "refresh_token":refresh_token,
                "openid":openid,
            })

    def qq_user_login(self,request):
        """网站用户和QQ进行绑定"""
        # 接收客户端提交
        username = request.data.get("username")
        password = request.data.get("password")
        # 单点调试
        # 查询用户是否存在
        ModelBackend = CustomAuthUserModelBackend()
        user = ModelBackend.authenticate(request, username, password)
        if user is None:
            return Response({"detail":"用户信息不存在或密码错误!"}, status=status.HTTP_400_BAD_REQUEST)
        else:
            """绑定账号和QQ"""
            return self._qq_user_bind(request,user)

    def qq_user_register(self,request):
        """游客注册账号和QQ进行绑定"""
        # 接收客户端提交
        nickname = request.data.get("nickname")
        mobile = request.data.get("mobile")
        password = request.data.get("password")
        sms_code = request.data.get("sms_code")

        serializers = UserModelSerializer(data={
            "nickname":nickname,
            "mobile":mobile,
            "password":password,
            "sms_code":sms_code,
        })

        serializers.is_valid(raise_exception=True)
        user = serializers.save()
        return self._qq_user_bind(request,user)

    def _qq_user_bind(self,request,user):
        """平台账号绑定QQ信息"""
        access_token = request.data.get("access_token")
        openid = request.data.get("openid")
        refresh_token = request.data.get("refresh_token")
        try:
            OauthUser.objects.create(
                user=user,
                openid=openid,
                name=1,
                access_token=access_token,
                refresh_token=refresh_token,
            )

            # 返回jwt登录状态
            from rest_framework_jwt.settings import api_settings

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(user)
            user.token = jwt_encode_handler(payload)
            serializer = UserModelSerializer(instance=user)
            return Response(serializer.data)
        except:
            return Response({"detail": "绑定QQ账号失败!请联系客服工作人员!"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


import base64,os
from django.db import transaction
from users.models import User
class WechatUserLoginViewSet(ViewSet):
    def get_user_by_openid(self,request):
        openid = request.data.get("openid")
        try:
            wechat_user = OauthUser.objects.get(name=2, openid=openid)
            # 返回jwt登录状态
            from rest_framework_jwt.settings import api_settings

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(wechat_user.user)
            wechat_user.user.token = jwt_encode_handler(payload)
            serializer = UserModelSerializer(instance=wechat_user.user)
            return Response(serializer.data)

        except OauthUser.DoesNotExist:
            return Response({
                "openid": openid,
            },status=status.HTTP_400_BAD_REQUEST)

    def create_wechat_user(self,request):
        """创建微信登录用户"""
        # 接收客户端提交
        nickname = request.data.get("nickname")
        avatar = request.data.get("avatar")
        openid = request.data.get("openid")
        username = "rr_%s" % (base64.b64encode(os.urandom(48))[:16]).decode().lower()
        password = (base64.b64encode(os.urandom(48))[:8]).decode().lower()

        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                user = User.objects.create_user(
                    nickname=nickname,
                    username=username,
                    password=password,
                )

                OauthUser.objects.create(
                    user=user,
                    openid=openid,
                    name=2,
                    access_token="",
                    refresh_token="",
                )

                return Response({"message":"微信登录成功!"})

            except:
                transaction.savepoint_rollback(save_id)
                return Response({"message":"微信登录失败!"})